#ifndef __OS_SOCKIOIF_H
#define __OS_SOCKIOIF_H

struct if_nameidx
{
    uint32_t if_index; 
    char *if_name;          //null terminated name 
};

enum 
{
    IFF_UP=0x01, //interface is up
    IFF_BROADCAST=0x2, //broadcast address valid
    IFF_DEBUG=0x4, //turn on debugging
    IFF_LOOPBACK=0x8, //is a loopback net
    IFF_POINTTOPOINT=0x10, //interface is point to point link
    IFF_NOTRAILERS=0x20, //avoid use of trailers
    IFF_RUNNING=0x40, //resource allocated
    IFF_NOARP=0x80, //no address resolution protocol
    IF_PROMISC=0x100, //receive all packets
    IFF_ALLMULTI=0x200, //receive all multicast packets
    IFF_MASTER=0x400, //master of a load balancer
    IFF_SLAVE=0x800, //slave of a load balancer
    IFF_MULITICAST=0x1000, //support multicast 
    IFF_PORTSEL=0x2000, //can set media type
    IFF_AUTOMEDIA=0x4000, //auto media select active
    IFF_DYNAMIC=0x8000, //dialup device with changing address
};

typedef struct ifaddr
{
    struct sockaddr ifa_addr; ///address of interface
    union 
    {
        struct sockaddr ifu_broadaddr;
        struct sockaddr ifu_dstaddr;
    }ifa_ifu;
    struct iface *ifa_ifp; //back-pointer to interface
    struct ifaddr *ifa_next; //next address for interface
}ifaddr_t;

#define ifa_broadaddr ifa_ifu.ifu_broadaddr //broadcast address
#define ifa_dstaddr ifa_ifu.ifu_dstaddr ///oter end of link

//device mapping struct
typedef struct ifmap
{
    uint64_t mem_start;
    uint64_t mem_end;
    uint16_t base_addr;
    uint8_t irq;
    uint8_t dma;
    uint8_t port;
}ifmap_t;

//interface request structure used for socket ioctl's
typedef struct ifreq
{
    #define IFHWADDRLEN 6
    #ifndef IFNAMSIZ 
    #define IFNAMSIZ 16
    #endif 

    union
    {
        char ifrn_name[IFNAMSIZ]; //interface name
    }ifr_ifrn;

    union 
    {
        struct sockaddr ifru_addr;
        struct sockaddr ifru_dstaddr;
        struct sockaddr ifru_broadaddr;
        struct sockaddr ifru_netmask;
        struct sockaddr ifru_hwaddr;
        int16_t ifru_flags; 
        int ifru_ivlaue;
        int ifru_mtu; 
        struct ifmap ifru_map;
        char ifru_slave[IFNAMSIZ];
        char ifru_newname[IFNAMSIZ]; 
    }ifr_ifru;
}ifreq_t;

#define ifr_name ifr_ifrn.ifrn_name //interface name
#define ifr_hwaddr ifr_ifru.ifru_hwaddr //MAC address
#define ifr_addr ifr_ifru.ifru_addr //address
#define ifr_dstaddr ifr_ifru.ifru_dstaddr //other end of p-p link
#define ifr_broadaddr ifr_ifru.ifru_broadaddr //broadcast address
#define ifr_netmask ifr_ifru.ifru_netmask //interface netmask
#define ifr_flags ifr_ifru.ifru_flags //flags
#define ifr_metric ifr_ifru.ifru_ivalue //metric
#define ifr_mtu ifr_ifru.ifru_mtu //mtu
#define ifr_map ifr_ifru.ifru_map //device map
#define ifr_slave ifr_ifru.ifru_slave //slave device
#define ifr_data ifr_ifru.ifru_data //for use by interface
#define ifr_ifindex ifr_ifru.ifru_ivalue //interface index
#define ifr_bandnwidth ifr_ifru.ifru_ivalue //link bandwidth
#define ifr_qlen ifr_ifru.ifru_ivalue //queue length
#define ifr_newname ifr_ifru.ifru_newname //new name

typedef struct ifconfig 
{
    int ifc_len; //size of buffer
    union 
    {
        char *ifcu_buff; //input from user to kernel
        struct ifreq *ifcu_req; //return from kernel to user
    }ifc_ifcu;
}ifconfig_t;

#define ifc_buff ifc_ifcu.ifcu_buff //buffer address
#define ifc_req ifc_ifcu.ifcu_req //array of struction return

#endif